using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web.UI;

namespace jQuery.ScriptManager
{
    public class jQueryManager : WebControl
    {
        private List<RegisterStartFunction> _readyFunctions;
        [Browsable(true), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty)]
        public List<RegisterStartFunction> ReadyFunctions
        {
            get
            {
                return _readyFunctions;
            }
            set
            {
                _readyFunctions = value;
            }
        }

        private List<RegisterScriptBlock> _otherFunctions;
        [Browsable(true), DefaultValue(null), PersistenceMode(PersistenceMode.InnerProperty)]
        public List<RegisterScriptBlock> Scripts
        {
            get
            {
                return _otherFunctions;
            }
            set
            {
                _otherFunctions = value;
            }
        }

        //http://blog.iridescence.no/Posts/EnsuringaSingleInstanceofaControlonaPage.aspx
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Page page = this.Page;
            if (page != null)
            {
                // check if an instance has already been added to the page
                if (page.Items.Contains(typeof(jQueryManager)))
                {
                    throw new InvalidOperationException("Only one instance of the jQueryManager control can be placed on a Page");
                }

                // add a reference to the Items collection for easy reference to the control; GetCurrent() will use this
                page.Items[typeof(jQueryManager)] = this;
            }

            Page.PreRenderComplete += new EventHandler(Page_PreRenderComplete);

            Page.ClientScript.RegisterClientScriptInclude("jqueryScript", Page.ClientScript.GetWebResourceUrl(this.GetType(), "jQuery.ScriptManager.includes.js.jquery-1.1.3.1.pack.js"));
        }

        void Page_PreRenderComplete(object sender, EventArgs e)
        {
            StringBuilder Start = new StringBuilder();

            if (ReadyFunctions != null)
            {
                Start.Append("$(document).ready(function(){");

                foreach (RegisterStartFunction r in ReadyFunctions)
                    Start.Append(r.FunctionName + "();\n");

                Start.Append("});\n\n");
            }

            if (Scripts != null)
            {
                foreach (RegisterScriptBlock r in Scripts)
                    Start.Append(r.ScriptBlock);
            }

            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "JQuery", Start.ToString(), true);
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnLoad(e);
        }

        /// <summary>
        /// Gets the instance of the jQueryManager on the page
        /// </summary>
        /// <param name="page">Current Page</param>
        /// <returns>Instance of the jQueryManager</returns>
        public static jQueryManager GetCurrent(Page page)
        {
            if (page == null)
            {
                throw new ArgumentNullException("page");
            }

            jQueryManager manager = page.Items[typeof(jQueryManager)] as jQueryManager;

            if (manager == null)
            {
                // no manager on Page - crash and burn
                throw new InvalidOperationException("Could not find a jQueryManager control on the page");
            }
            return manager;
        }

        /// <summary>
        /// Registers a script
        /// </summary>
        /// <param name="Script">The full contents of the script (function name(){ ... })</param>
        public void RegisterScript(string Script)
        {
            if (_otherFunctions == null)
                _otherFunctions = new List<RegisterScriptBlock>();

            _otherFunctions.Add(new RegisterScriptBlock(Script));
        }

        /// <summary>
        /// Registers the name of a function to call on $(document).ready
        /// </summary>
        /// <param name="FunctionName">The name of the function</param>
        public void RegisterStartFunction(string FunctionName)
        {
            if (_readyFunctions == null)
                _readyFunctions = new List<RegisterStartFunction>();

            Boolean pass = true;
            foreach (RegisterStartFunction reg in _readyFunctions)
            {
                if (reg.FunctionName == FunctionName)
                {
                    pass = false;
                }
            }

            if (pass)
            {
                _readyFunctions.Add(new RegisterStartFunction(FunctionName));
            }
        }
    }
}
